package linc.spring.demo;

import linc.spring.demo.bean.User;
import linc.spring.demo.config.ApplicationConfiguration;
import org.junit.Test;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;

/**
 * @author yqlin
 * @date 2021/9/7 00:15
 * @description 在Spring源码中所提供的BeanDefinition读取器（BeanDefinitionReader），
 * 这些BeanDefinitionReader在我们使用Spring时用得少，但在Spring源码中用得多，相当于Spring源码的基础设施。
 */
public class SpringBeanDefinitionReaderTest {
    /**
     * 可以直接把某个类转换为BeanDefinition，并且会解析该类上的注解
     * 它能解析的注解是：@Conditional，@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description
     */
    @Test
    public void testAnnotatedBeanDefinitionReader() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
        AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(applicationContext);
        reader.registerBean(User.class);
        // linc.spring.demo.bean.User@51b7e5df
        System.out.println(applicationContext.getBean("user"));
    }

    /**
     * 可以解析<bean/>标签
     */
    @Test
    public void testXmlBeanDefinitionReader() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(applicationContext);
        xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
        // linc.spring.demo.bean.User@45dd4eda
        System.out.println(applicationContext.getBean("user"));
    }

    /**
     * ClassPathBeanDefinitionScanner是扫描器，
     * 但是它的作用和BeanDefinitionReader类似，它可以进行扫描，扫描某个包路径，对扫描到的类进行解析，
     * 比如，扫描到的类上如果存在@Component注解，那么就会把这个类解析为一个BeanDefinition
     */
    @Test
    public void testClassPathBeanDefinitionScanner() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ApplicationConfiguration.class);
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(applicationContext);
        scanner.scan("linc.spring.demo");
        System.out.println(applicationContext.getBean("userService"));
    }
}
